package com.ray.business.service.compose;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ray.business.builder.BusinessVOBuilder;
import com.ray.business.service.ProdBusinessDeductionService;
import com.ray.business.service.ProdBusinessInService;
import com.ray.business.service.ProdBusinessService;
import com.ray.business.service.ProdOrderGoodsService;
import com.ray.business.table.entity.ProdBusiness;
import com.ray.business.table.entity.ProdBusinessDeduction;
import com.ray.business.table.entity.ProdBusinessIn;
import com.ray.business.table.entity.ProdOrderGoods;
import com.ray.business.table.vo.BusinessVO;
import com.ray.system.service.compose.RedisService;
import com.ray.woodencreate.beans.LoginUser;
import com.ray.woodencreate.exception.BusinessExceptionFactory;
import com.ray.woodencreate.util.Assert;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author bo shen
 * @Description: 业务订单服务
 * @Class: BusinessService
 * @Package com.ray.business.service.compose
 * @date 2020/6/13 19:00
 * @company <p>Ray快速开发平台</p>
 * @updateRecord time(修改时间)  author(修改人)   desc(修改内容)
 */
@Service
@Slf4j
public class BusinessService {
    @Autowired
    private ProdBusinessService prodBusinessService;
    @Autowired
    private ProdBusinessInService prodBusinessInService;
    @Autowired
    private ProdOrderGoodsService prodOrderGoodsService;
    @Autowired
    private ProdBusinessDeductionService prodBusinessDeductionService;
    @Autowired
    private RedisService redisService;

    /**
     * 完成订单
     *
     * @param prodBusiness
     * @param loginUser
     * @return
     */
    public Boolean finishOrder(ProdBusiness prodBusiness, LoginUser loginUser) {
        List<ProdBusinessIn> prodBusinessIns = prodBusinessInService.listAll(prodBusiness.getBusinessCode(), loginUser);
        Map<String, BigDecimal> decimalMap = new HashMap<>();
        Map<String, Integer> integerMap = new HashMap<>();
        //分组求和
        prodBusinessIns.forEach(prodBusinessIn -> {
            BigDecimal quantity = decimalMap.get(prodBusinessIn.getGoodsCode());
            if (ObjectUtil.isNull(quantity)) {
                quantity = new BigDecimal(0);
            }
            Integer total = integerMap.get(prodBusinessIn.getGoodsCode());
            if (ObjectUtil.isNull(total)) {
                total = 0;
            }
            integerMap.put(prodBusinessIn.getGoodsCode(), total + prodBusinessIn.getTotal());
            decimalMap.put(prodBusinessIn.getGoodsCode(), quantity.add(prodBusinessIn.getQuantity()));
        });
        //更新数量
        for (String goodCode : decimalMap.keySet()) {
            ProdOrderGoods orderGoods = prodOrderGoodsService.queryOrderGoodsByGoodsCode(prodBusiness.getOrderNo(), goodCode, loginUser);
            if (ObjectUtil.isNotNull(orderGoods)) {
                //完成数量
                BigDecimal finishQuantity = NumberUtil.null2Zero(orderGoods.getFinishQuantity()).add(decimalMap.get(goodCode));
                //完成卷数
                Integer finishTotal = orderGoods.getTotal() + integerMap.get(goodCode);
                if (!prodOrderGoodsService.updateFinishQuantity(prodBusiness.getOrderNo(), goodCode,
                        finishQuantity, finishTotal, orderGoods.getUpdateVersion(), loginUser)) {
                    log.info("更新订单完成数量异常");
                    throw BusinessExceptionFactory.newException("更新订单完成数量异常");
                }
            }
        }
        return prodBusinessService.finishOrder(prodBusiness.getBusinessCode(), loginUser);
    }


    /**
     * 完成订单
     *
     * @param prodBusiness
     * @param loginUser
     * @return
     */
    public Boolean wmsCancel(ProdBusiness prodBusiness, LoginUser loginUser) {
        List<ProdBusinessIn> prodBusinessIns = prodBusinessInService.listAll(prodBusiness.getBusinessCode(), loginUser);
        Map<String, BigDecimal> decimalMap = new HashMap<>();
        Map<String, Integer> integerMap = new HashMap<>();

        //分组求和
        prodBusinessIns.forEach(prodBusinessIn -> {
            BigDecimal quantity = decimalMap.get(prodBusinessIn.getGoodsCode());
            if (ObjectUtil.isNull(quantity)) {
                quantity = new BigDecimal(0);
            }
            decimalMap.put(prodBusinessIn.getGoodsCode(), quantity.add(prodBusinessIn.getQuantity()));

            Integer total = integerMap.get(prodBusinessIn.getGoodsCode());
            if (ObjectUtil.isNull(total)) {
                total = 0;
            }
            integerMap.put(prodBusinessIn.getGoodsCode(), total + prodBusinessIn.getTotal());
        });
        //更新数量
        for (String goodCode : decimalMap.keySet()) {
            ProdOrderGoods orderGoods = prodOrderGoodsService.queryOrderGoodsByGoodsCode(prodBusiness.getOrderNo(), goodCode, loginUser);
            if (ObjectUtil.isNotNull(orderGoods)) {
                BigDecimal finishQuantity = NumberUtil.null2Zero(orderGoods.getFinishQuantity()).subtract(decimalMap.get(goodCode));
                Integer finishTotal = orderGoods.getTotal() - integerMap.get(goodCode);
                if (!prodOrderGoodsService.updateFinishQuantity(prodBusiness.getOrderNo(), goodCode, finishQuantity, finishTotal
                        , orderGoods.getUpdateVersion(), loginUser)) {
                    log.info("更新订单完成数量异常");
                    throw BusinessExceptionFactory.newException("更新订单完成数量异常");
                }
            }
        }
        return true;
    }

    /**
     * 查询
     *
     * @param billNo
     * @param customerName
     * @param loginUser
     * @return
     */
    public List<BusinessVO> queryBusinessByBIllNo(String billNo, String customerName, LoginUser loginUser) {
        Assert.hasLength(billNo, "参数[billNo]不能为空");
        //获取对账单对应的扣款单
        List<ProdBusinessDeduction> prodBusinessDeductions = prodBusinessDeductionService.listByBillNo(billNo, loginUser);
        final Map<String, BigDecimal> decimalMap = prodBusinessDeductions.stream()
                .collect(Collectors.groupingBy(ProdBusinessDeduction::getBusinessCode, Collectors.reducing(BigDecimal.ZERO, ProdBusinessDeduction::getAmount, BigDecimal::add)));

        List<ProdBusiness> prodBusinesses = prodBusinessService.listByBillNo(billNo, loginUser);
        //转换
        return prodBusinesses.stream().map(prodBusiness -> {
            return new BusinessVOBuilder().append(prodBusiness).appendCustomerName(customerName).appendDeductionAmount(decimalMap.get(prodBusiness.getBusinessCode())).bulid();
        }).collect(Collectors.toList());
    }

    public String getNumber() {
        StringBuilder unKey = new StringBuilder("");
        String key = DateUtil.format(new Date(), "yyMMdd");
        //获取序列
        unKey.append(key);
        Long value = redisService.getNext(key);
        unKey.append(String.format("%04d", value));
        return unKey.toString();
    }
}
